package com.hzgj.bcl.soa.rpc.message;

import com.hzgj.bcl.soa.util.Constants;

import java.util.HashMap;
import java.util.Map;

import lombok.Getter;

import static com.hzgj.bcl.soa.util.Constants.MESSAGE_TYPE;

public class Message {

    public static final int REQ = 0;
    public static final int RSP = 1;
    public static final int EXC_RSP = 2; // exception

    @Getter
    protected Object payload;
    protected Map<String, Object> headers;
    protected volatile short flags;

    public Message(Object payload) {
        setPayload(payload);
        headers = new HashMap<>();
    }

    public Message() {
        this(null);
    }

    public int getLength() {
        if (payload instanceof byte[]) {
            return ((byte[]) payload).length;
        }
        throw new RuntimeException("payload must be byte[] when invoke getLength");
    }

    public Message putHeader(String id, Object hdr) {
        headers.put(id, hdr);
        return this;
    }

    public Message putHeaders(Map<String, Object> headers) {
        this.headers.putAll(headers);
        return this;
    }

    public Message setPayload(Object payload) {
        this.payload = payload;
        return this;
    }

    public Object getHeader(String id) {
        return headers.get(id);
    }

    public Map<String, Object> getHeaders() {
        return headers;
    }

    public Message copy(boolean copy_payload) {
        Message retval = new Message(false);
        retval.flags = flags;
        if (copy_payload && payload != null) {
            retval.payload = payload;
        }
        retval.headers = headers;
        return retval;
    }

    @Override
    public String toString() {
        return " [ headers=" + headers + "]";
    }

    public Long getMessageId() {
        return (Long) headers.get(Constants.MESSAGE_SID);
    }

    public String getService() {
        return (String) headers.get(Constants.MESSAGE_HEADER_TARGET_SERVICE);
    }

    public String getMethod() {
        return (String) headers.get(Constants.MESSAGE_HEADER_METHOD);
    }

    public String getLbRule() {
        return (String) headers.get(Constants.MESSAGE_HEADER_LBRULE);
    }

    public Byte getSerializationId() {
        return (Byte) headers.get(Constants.MESSAGE_HEADER_SERIALIZATION_ID);
    }

    public boolean isRequest() {
        return (int) headers.get(MESSAGE_TYPE) == REQ;
    }
}
